<template>
  <div>
    <el-row>
      <el-col :span="4" style="padding-right: 10px">
        <el-card class="chat">
          <div class="button-center">
            <el-button type="primary" icon="el-icon-plus" @click="add" class="el-button"
              >新增聊天菜单</el-button
            >
          </div>
          <el-divider class="li-divider"></el-divider>
          <el-menu :default-active="chatInfo.chatMenuId" class="el-menu-vertical-demo">
            <chat-menu-item
              v-for="item in chatMenuListInfo"
              :key="item.id"
              :menu-item="item"
              @menu-item-updated="updateMenuItem"
              @menu-item-click="clickMenuItem"
            />
          </el-menu>
        </el-card>
      </el-col>
      <el-col :span="20">
        <el-card class="chat-two">
          <div class="chat-top">
            <!-- <span style="font-size: 20px; color: #000">AI助手</span>
            &nbsp;
            <span>v1.0.0 |</span>
            &nbsp;
            <span style="font-size: 15px; color: #005320" @click="alConfig"
              >配置</span
            > -->
            <el-radio v-model="chatInfo.contentType" :label="0">通义千问</el-radio>
            <el-radio v-model="chatInfo.contentType" :label="1">通义万象</el-radio>
          </div>
          <div class="chat-content" ref="scrollContainer">
            <div class="chat-content-item" v-for="item in chatContentList" :key="item.id">
              <div class="ask">
                <el-avatar :size="30" style="margin-right: 10px">
                  <img :src="userImg" />
                </el-avatar>
                <div class="ask-item" v-html="item.askContent"></div>
              </div>
              <div class="reply">
                <el-avatar :size="30" style="margin-right: 10px">
                  <img src="../../assets/images/giteelog.png" />
                </el-avatar>
                <div class="reply-item">
                  <div
                    v-if="item.id == chatId"
                    class="reply-item-item"
                    v-html="item.replyContent"
                    v-loading="loading"
                    element-loading-text="加载中请稍等！！"
                    v-highlight
                  ></div>
                  <div
                    v-else
                    class="reply-item-item"
                    v-html="item.replyContent"
                    v-highlight
                  ></div>
                </div>
              </div>
            </div>
          </div>
          <div class="chat-content-input">
            <el-input
              v-model="chatInfo.question"
              type="textarea"
              :rows="4"
              placeholder="请输入内容"
              :disabled="isDisabled"
              @keydown.enter.native="sendMsgEnter"
            ></el-input>
            <el-button
              :disabled="isDisabled"
              type="primary"
              icon="el-icon-plus"
              @click="sendMsg"
              style="height: 95px"
              >发送</el-button
            >
          </div>
        </el-card>
      </el-col>
    </el-row>
    <el-dialog title="AI-配置" :visible.sync="dialogVisible" width="400px">
      <div class="ai-config">
        <div>
          <el-radio v-model="chatInfo.contentType" :label="0">通义千问</el-radio>
          <el-radio v-model="chatInfo.contentType" :label="1">通义万象</el-radio>
        </div>
        <div v-if="chatInfo.contentType == 0" style="margin-top: 10px">
          <el-radio v-model="chatInfo.model" label="qwen-v1">普通搜索</el-radio>
          <el-radio v-model="chatInfo.model" label="qwen-plus-v1">增强搜索</el-radio>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getChatMenuList, addChatMenu, start, list } from "@/services/chat";
import ChatMenuItem from "@/components/chatMenuItem.vue";
import MarkdownIt from "markdown-it";
import "highlight.js/styles/base16/atelier-cave-light.css";
export default {
  components: {
    ChatMenuItem,
  },
  name: "AlHelper",
  data() {
    return {
      dialogVisible: false,
      meunBindId: "",
      chatInfo: {
        question: "",
        chatMenuId: "",
        model: "qwen-v1",
      },
      chatMenuListInfo: [],
      addChatInfo: {
        chatMenuName: "新对话窗口",
      },
      chatMenuQuery: {
        chatMenuName: "",
      },
      updChatInfo: {},
      chatContentList: [],
      isDisabled: false,
      loading: false,
      chatId: "",
    };
  },
  computed: {
    userImg() {
      return JSON.parse(sessionStorage.getItem("userData")).headPic;
    },
  },
  mounted() {
    this.chatMenuList();
  },

  methods: {
    //配置
    alConfig() {
      this.dialogVisible = true;
    },
    //底部
    scrollToBottom() {
      this.$nextTick(() => {
        const container = this.$refs.scrollContainer;
        container.scrollTop = container.scrollHeight;
      });
    },
    //编辑菜单名称
    editMenu() {
      this.editing = true;
    },
    //新增聊天
    add() {
      addChatMenu(this.addChatInfo)
        .then((res) => {
          if (res.data) {
            this.chatMenuList();
          }
        })
        .catch((error) => {});
    },
    //聊天菜单列表
    chatMenuList() {
      getChatMenuList(this.chatMenuQuery)
        .then((res) => {
          this.chatMenuListInfo = res.data;
          this.flush();
          if (res.data.length > 0) {
            this.clickMenuItem(res.data[0]);
          }
        })
        .catch((error) => {});
    },
    flush() {
      this.chatContentList = [];
      this.chatInfo = {
        question: "",
        chatMenuId: "",
        contentType: 0,
      };
    },
    updateMenuItem() {
      this.chatMenuList();
    },
    //菜单回调
    clickMenuItem(menuItem) {
      this.chatInfo.chatMenuId = menuItem.id;
      list(menuItem.id)
        .then((res) => {
          this.chatContentList = res.data;
          const md = new MarkdownIt();
          this.chatContentList.forEach((i) => {
            i.askContent = md.render(i.askContent);
            i.replyContent = md.render(i.replyContent);
          });
          this.scrollToBottom();
        })
        .catch((error) => {});
    },
    sendMsg() {
      if (this.chatInfo.question == "") {
        this.$message({
          type: "error",
          message: "请输入询问内容",
        });
        return;
      }
      if (this.chatInfo.chatMenuId == "") {
        addChatMenu(this.addChatInfo)
          .then((res) => {
            if (res.data) {
              this.chatInfo.chatMenuId = res.data;
              getChatMenuList(this.chatMenuQuery)
                .then((res) => {
                  this.chatMenuListInfo = res.data;
                  if (res.data.length > 0) {
                    this.chatInfo.chatMenuId = res.data[0].id;
                    this.sseWatch(this.chatInfo.chatMenuId);
                  }
                })
                .catch((error) => {});
            }
          })
          .catch((error) => {});
      } else {
        this.sseWatch(this.chatInfo.chatMenuId);
      }
    },
    sendMsgEnter() {
      if (!this.isDisabled) {
        this.sendMsg();
      }
    },
    //sse监听
    sseWatch(chatMenuId) {
      if (!!window.EventSource) {
        var md = new MarkdownIt();
        const id = Math.floor(Math.random() * 10000000) + "";
        this.chatId = id;
        var chatContent = {
          id: id,
          askContent: md.render(this.chatInfo.question),
          replyContent: this.chatInfo.contentType == 1 ? "<br><br><br><br>" : "",
        };
        var source = new EventSource(
           `http://admin.hx.xijia.plus/api/chat/addSse?id=${chatMenuId}`
        );
        // var source = new EventSource(
        //   `http://127.0.0.1:9090/api/chat/addSse?id=${chatMenuId}`
        // );
        source.onerror = (e) => {
          source.close();
          this.isDisabled = false;
        };
        //建立链接
        source.addEventListener("open", (e) => {});
        //监听开始消息
        source.addEventListener("start", (e) => {
          this.chatContentList.push(chatContent);
          this.loading = true;
          this.scrollToBottom();
          this.isDisabled = true;
          start(this.chatInfo)
            .then((res) => {})
            .catch((error) => {
              this.isDisabled = true;
              this.chatInfo.question = "";
            });
          this.chatInfo.question = "";
        });
        // 监听数据
        source.addEventListener("data", (e) => {
          this.loading = false;
          chatContent.replyContent = md.render(JSON.parse(e.data).text);
          this.scrollToBottom();
        });
        //监听后台err消息
        source.addEventListener("err", (e) => {
          this.loading = false;
          chatContent.replyContent = md.render(e.data);
          this.scrollToBottom();
        });
      } else {
        console.log("你的浏览器不支持sse ");
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.chat {
  overflow: auto;
  height: 87vh;
  width: 100%;

  .button-center {
    display: flex;
    margin-top: 10px;
    width: 100%;
    align-items: center;
    justify-content: center;
  }

  .li-divider {
    width: 100%;
    margin-bottom: 3px;
    margin-top: 14px;
  }
  .chat-menu {
    display: flex;
    justify-content: space-between;

    .menu-input {
      overflow: hidden;
    }
  }
  /deep/ .el-dropdown-menu__item,
  .el-menu-item {
    padding: 0;
  }
}

.chat-two {
  position: relative;
  height: 87vh;
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  /* 防止 .chat-content 的内容溢出 */
  .chat-top {
    height: 4vh;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .chat-content {
    flex: 1;
    overflow-y: auto;
    margin-bottom: 2%;
    height: 71vh;

    .chat-content-item {
      .ask {
        margin-top: 15px;
        display: flex;
        justify-content: flex-end;
        /* 将内容靠右对齐 */
        .ask-item {
          line-height: 1.5;
          max-width: 30%;
          margin-right: 10px;
        }
      }
      .reply {
        margin-top: 15px;
        display: flex;
        .reply-item {
          background-color: #f3f3ff;
          width: 60%;
          border-radius: 10px;
          .reply-item-item {
            margin: 20px;
            font-size: 15px;
            line-height: 1.5;
          }
          /deep/ img {
            max-width: 100%;
          }
          /deep/ pre code.hljs {
            margin-top: 10px;
            margin-bottom: 10px;
            border-radius: 10px;
          }
        }
      }
    }
  }
  .chat-content-input {
    position: sticky;
    bottom: 0;
    left: 0;
    display: flex;
    width: 50%;
    margin-left: 25%;
    height: 100px;
  }
}
/deep/ .el-card__body {
  padding: 0px;
}

.el-button + .el-button,
.el-checkbox.is-bordered + .el-checkbox.is-bordered {
  margin-left: 0px;
}
.ai-config {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
</style>
